#ifndef _enc28j60_H
#define _enc28j60_H

/* instruction set, 3b opcode | argument, except RBM,WBM,SRC */

#define	ENC28J60_RCR	0x00	// read control register
#define	ENC28J60_RBM	0x3A	// read buffer memory
#define ENC28J60_WCR	0x40	// write control register
#define ENC28J60_WBM	0x7A	// write buffer memory
#define ENC28J60_BFS	0x80	// bit filed set
#define	ENC28J60_BFC	0xA0	// bit field clear
#define	ENC28J60_SRC	0xFF	// soft reset

/* - Register address        (bits 0-4)*/
/* - Bank number        (bits 5-6)*/
/* - MAC/PHY indicator        (bit 7)*/
#define ENC28J60_ADDR_MASK        0x1F
#define ENC28J60_BANK_MASK        0x60
#define ENC28J60_SPRD_MASK        0x80

/* registers */

#define ENC28J60_BANK0()	ENC28J60_ECON1 &= 0xFC
#define	ENC28J60_BANK1()	ENC28J60_ECON1 = ( ENC28J60_ECON1 & 0xFC ) | 0x01
#define ENC28J60_BANK2()	ENC28J60_ECON1 = ( ENC28J60_ECON1 & 0xFC ) | 0x02
#define ENC28J60_BANK3()	ENC28J60_ECON1 |= 0x03

/* COMMON */
#define ENC28J60_EIE		0x1B
    #define EIE_INTIE        0x80
    #define EIE_PKTIE        0x40
    #define EIE_DMAIE        0x20
    #define EIE_LINKIE       0x10
    #define EIE_TXIE         0x08
    #define EIE_WOLIE        0x04
    #define EIE_TXERIE       0x02
    #define EIE_RXERIE       0x01
#define ENC28J60_EIR		0x1C
    #define EIR_PKTIF        0x40
    #define EIR_DMAIF        0x20
    #define EIR_LINKIF       0x10
    #define EIR_TXIF         0x08
    #define EIR_WOLIF        0x04
    #define EIR_TXERIF       0x02
    #define EIR_RXERIF       0x01
#define ENC28J60_ESTAT		0x1D
    #define ESTAT_INT        0x80
    #define ESTAT_LATECOL    0x10
    #define ESTAT_RXBUSY     0x04
    #define ESTAT_TXABRT     0x02
    #define ESTAT_CLKRDY     0x01
#define ENC28J60_ECON2		0x1E
    #define ECON2_AUTOINC    0x80
    #define ECON2_PKTDEC     0x40
    #define ECON2_PWRSV      0x20
    #define ECON2_VRPS       0x08
#define ENC28J60_ECON1		0x1F		
    #define ECON1_TXRST      0x80
    #define ECON1_RXRST      0x40
    #define ECON1_DMAST      0x20
    #define ECON1_CSUMEN     0x10
    #define ECON1_TXRTS      0x08
    #define ECON1_RXEN       0x04
    #define ECON1_BSEL1      0x02
    #define ECON1_BSEL0      0x01


/* bank 0 */
#define ENC28J60_ERDPTL		(0x00|0x00)
#define ENC28J60_ERDPTH		(0x01|0x00)
#define ENC28J60_EWRPTL		(0x02|0x00)
#define ENC28J60_EWRPTH		(0x03|0x00)
#define ENC28J60_ETXSTL		(0x04|0x00)
#define ENC28J60_ETXSTH		(0x05|0x00)
#define ENC28J60_ETXNDL		(0x06|0x00)
#define ENC28J60_ETXNDH		(0x07|0x00)
#define ENC28J60_ERXSTL		(0x08|0x00)
#define ENC28J60_ERXSTH		(0x09|0x00)
#define ENC28J60_ERXNDL		(0x0A|0x00)
#define ENC28J60_ERXNDH		(0x0B|0x00)
#define ENC28J60_ERXRDPTL	(0x0C|0x00)
#define ENC28J60_ERXRDPTH	(0x0D|0x00)
#define ENC28J60_ERXWRPTL	(0x0E|0x00)
#define ENC28J60_ERXWRPTH	(0x0F|0x00)
#define ENC28J60_EDMASTL	(0x10|0x00)
#define ENC28J60_EDMASTH	(0x11|0x00)
#define ENC28J60_EDMANDL	(0x12|0x00)
#define ENC28J60_EDMANDH	(0x13|0x00)
#define ENC28J60_EDMADSTL	(0x14|0x00)
#define ENC28J60_EDMADSTH	(0x15|0x00)
#define ENC28J60_EDMACSL	(0x16|0x00)
#define ENC28J60_EDMACSH	(0x17|0x00)

/* BANK 1 */
#define ENC28J60_ETH0		(0x00|0x20)
#define ENC28J60_ETH1		(0x01|0x20)
#define ENC28J60_ETH2		(0x02|0x20)
#define ENC28J60_ETH3		(0x03|0x20)
#define ENC28J60_ETH4		(0x04|0x20)
#define ENC28J60_ETH5		(0x05|0x20)
#define ENC28J60_ETH6		(0x06|0x20)
#define ENC28J60_ETH7		(0x07|0x20)
#define ENC28J60_EPMM0		(0x08|0x20)
#define ENC28J60_EPMM1		(0x09|0x20)
#define ENC28J60_EPMM2		(0x0A|0x20)
#define ENC28J60_EPMM3		(0x0B|0x20)
#define ENC28J60_EPMM4		(0x0C|0x20)
#define ENC28J60_EPMM5		(0x0D|0x20)
#define ENC28J60_EPMM6		(0x0E|0x20)
#define ENC28J60_EPMM7		(0x0F|0x20)
#define ENC28J60_EPMSCL		(0x10|0x20)
#define ENC28J60_EPMSCH		(0x11|0x20)
#define ENC28J60_EPMOL		(0x14|0x20)
#define ENC28J60_EPMOH		(0x15|0x20)
#define ENC28J60_ERXFCON	(0x18|0x20)
    #define ERXFCON_BCEN	0x01
    #define ERXFCON_MCEN	0x02
    #define ERXFCON_HTEN	0x04
    #define ERXFCON_MPEN	0x08
    #define ERXFCON_PMEN	0x10
    #define ERXFCON_CRCEN	0x20
    #define ERXFCON_ANDOR	0x40
    #define ERXFCON_UCEN	0x80
#define ENC28J60_EPKTCNT	(0x19|0x20)

/* BANK 2*/
#define ENC28J60_MACON1		(0x00|0x40|0x80)
	#define MACON1_MARXEN	0x01
	#define MACON1_PASSALL	0x02
	#define MACON1_RXPAUS	0x04
	#define MACON1_TXPAUS	0x08
	#define MACON1_r		0x10
#define ENC28J60_MACON3		(0x02|0x40|0x80)
	#define MACON3_FULDPX	0x01
	#define MACON3_FRMLEN	0x02
	#define MACON3_HFRMEN	0x04
	#define MACON3_PHDREN	0x08
	#define MACON3_TXCRCEN	0x10
	#define MACON3_PADCFG0	0x20
	#define MACON3_PADCFG1	0x40
	#define MACON3_PADCFG2	0x80
#define ENC28J60_MACON4		(0x03|0x40|0x80)
#define ENC28J60_MABBIPG	(0x04|0x40|0x80)
#define ENC28J60_MAIPGL		(0x06|0x40|0x80)
#define ENC28J60_MAIPGH		(0x07|0x40|0x80)
#define ENC28J60_MACLCON1	(0x08|0x40|0x80)
#define ENC28J60_MACLCON2	(0x09|0x40|0x80)
#define ENC28J60_MAMXFLL	(0x0A|0x40|0x80)
#define ENC28J60_MAMXFLH	(0x0B|0x40|0x80)
#define ENC28J60_MICMD		(0x12|0x40|0x80)
#define ENC28J60_MIREGADR	(0x14|0x40|0x80)
#define ENC28J60_MIWRL		(0x16|0x40|0x80)
#define ENC28J60_MIWRH		(0x17|0x40|0x80)
#define ENC28J60_MIRDL		(0x18|0x40|0x80)
#define ENC28J60_MIRDH		(0x19|0x40|0x80)

/* BANK3 */
#define ENC28J60_MAADR5		(0x00|0x60|0x80)
#define ENC28J60_MAADR6		(0x01|0x60|0x80)
#define ENC28J60_MAADR3		(0x02|0x60|0x80)
#define ENC28J60_MAADR4		(0x03|0x60|0x80)
#define ENC28J60_MAADR1		(0x04|0x60|0x80)
#define ENC28J60_MAADR2		(0x05|0x60|0x80)
#define ENC28J60_EBSTSD		(0x06|0x60)
#define ENC28J60_EBSTCON	(0x07|0x60)
#define ENC28J60_EBSTCSL	(0x08|0x60)
#define ENC28J60_EBSTCSH	(0x09|0x60)
#define ENC28J60_MISTAT		(0x0A|0x60|0x80)
#define ENC28J60_EREVID		(0x12|0x60)
#define ENC28J60_ECOCON		(0x15|0x60)
#define ENC28J60_EFLOCON	(0x17|0x60)
#define ENC28J60_EPAUSL		(0x18|0x60)
#define ENC28J60_EPAUSH		(0x19|0x60)

/* PHY registers */
#define ENC28J60_PHCON1		0x00
#define ENC28J60_PHSTAT1	0x01
#define ENC28J60_PHD1		0x02
#define ENC28J60_PHD2		0x03
#define ENC28J60_PHCON2		0x10
#define ENC28J60_PHSTAT2	0x11
#define ENC28J60_PHE		0x12
#define ENC28J60_PHR		0x13
#define ENC28J60_PHLCON		0x14

#define RXSTART_INIT     0x0000
#define RXSTOP_INIT      (0x1FFF-0x0600-1)
#define TXSTART_INIT     (0x1FFF-0x0600)
#define TXSTOP_INIT      0x1FFF
/*/#define        MAX_FRAMELEN        1518        // maximum ethernet frame length*/
#define		MAX_FRAMELEN		1512


/* functions */

byte ENC28J60_ReadOp( byte op, byte addr);
void ENC28J60_WriteOp( byte op, byte addr, byte data);
void ENC28J60_ReadBuffer( UINT16 len, byte* data );
void ENC28J60_WriteBuffer( UINT16 len, byte* data );
void ENC28J60_SetBank( byte addr );
byte ENC28J60_Read( byte addr );
void ENC28J60_Write( byte addr, byte data );
void ENC28J60_PhyWrite( byte addr, UINT16 data);
void ENC28J60_SendPacket( UINT16 len, byte* packet );
UINT16 ENC28J60_ReceivePacket( UINT16 max_len, byte* packet );
void ENC28J60_Init( byte* macaddr );

void ENC28J60_SPIwrite( byte data );
byte ENC28J60_SPIread(void);

#endif